mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge to mysql-next-mr
This commit is contained in:
@@ -2766,8 +2766,24 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
|
||||
|
||||
if (part_info->part_expr->null_value)
|
||||
{
|
||||
DBUG_RETURN(0);
|
||||
/*
|
||||
Special handling for MONOTONIC functions that can return NULL for
|
||||
values that are comparable. I.e.
|
||||
'2000-00-00' can be compared to '2000-01-01' but TO_DAYS('2000-00-00')
|
||||
returns NULL which cannot be compared used <, >, <=, >= etc.
|
||||
|
||||
Otherwise, just return the the first index (lowest value).
|
||||
*/
|
||||
enum_monotonicity_info monotonic;
|
||||
monotonic= part_info->part_expr->get_monotonicity_info();
|
||||
if (monotonic != MONOTONIC_INCREASING_NOT_NULL &&
|
||||
monotonic != MONOTONIC_STRICT_INCREASING_NOT_NULL)
|
||||
{
|
||||
/* F(col) can not return NULL, return index with lowest value */
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (unsigned_flag)
|
||||
part_func_value-= 0x8000000000000000ULL;
|
||||
DBUG_ASSERT(part_info->no_list_values);
|
||||
@@ -2916,11 +2932,29 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
|
||||
|
||||
if (part_info->part_expr->null_value)
|
||||
{
|
||||
uint32 ret_part_id= 0;
|
||||
if (!left_endpoint && include_endpoint)
|
||||
ret_part_id= 1;
|
||||
DBUG_RETURN(ret_part_id);
|
||||
/*
|
||||
Special handling for MONOTONIC functions that can return NULL for
|
||||
values that are comparable. I.e.
|
||||
'2000-00-00' can be compared to '2000-01-01' but TO_DAYS('2000-00-00')
|
||||
returns NULL which cannot be compared used <, >, <=, >= etc.
|
||||
|
||||
Otherwise, just return the first partition
|
||||
(may be included if not left endpoint)
|
||||
*/
|
||||
enum_monotonicity_info monotonic;
|
||||
monotonic= part_info->part_expr->get_monotonicity_info();
|
||||
if (monotonic != MONOTONIC_INCREASING_NOT_NULL &&
|
||||
monotonic != MONOTONIC_STRICT_INCREASING_NOT_NULL)
|
||||
{
|
||||
/* F(col) can not return NULL, return partition with lowest value */
|
||||
if (!left_endpoint && include_endpoint)
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (unsigned_flag)
|
||||
part_func_value-= 0x8000000000000000ULL;
|
||||
if (left_endpoint && !include_endpoint)
|
||||
@@ -6698,6 +6732,7 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
|
||||
Field *field= part_info->part_field_array[0];
|
||||
uint32 max_endpoint_val;
|
||||
get_endpoint_func get_endpoint;
|
||||
bool can_match_multiple_values; /* is not '=' */
|
||||
uint field_len= field->pack_length_in_rec();
|
||||
part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
|
||||
|
||||
@@ -6735,6 +6770,23 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
|
||||
can_match_multiple_values= (flags || !min_value || !max_value ||
|
||||
memcmp(min_value, max_value, field_len));
|
||||
if (can_match_multiple_values &&
|
||||
(part_info->part_type == RANGE_PARTITION ||
|
||||
part_info->has_null_value))
|
||||
{
|
||||
/* Range scan on RANGE or LIST partitioned table */
|
||||
enum_monotonicity_info monotonic;
|
||||
monotonic= part_info->part_expr->get_monotonicity_info();
|
||||
if (monotonic == MONOTONIC_INCREASING_NOT_NULL ||
|
||||
monotonic == MONOTONIC_STRICT_INCREASING_NOT_NULL)
|
||||
{
|
||||
/* col is NOT NULL, but F(col) can return NULL, add NULL partition */
|
||||
part_iter->ret_null_part= part_iter->ret_null_part_orig= TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Find minimum: Do special handling if the interval has left bound in form
|
||||
@@ -6767,6 +6819,14 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
|
||||
store_key_image_to_rec(field, min_value, field_len);
|
||||
bool include_endp= !test(flags & NEAR_MIN);
|
||||
part_iter->part_nums.start= get_endpoint(part_info, 1, include_endp);
|
||||
if (!can_match_multiple_values && part_info->part_expr->null_value)
|
||||
{
|
||||
/* col = x and F(x) = NULL -> only search NULL partition */
|
||||
part_iter->part_nums.cur= part_iter->part_nums.start= 0;
|
||||
part_iter->part_nums.end= 0;
|
||||
part_iter->ret_null_part= part_iter->ret_null_part_orig= TRUE;
|
||||
return 1;
|
||||
}
|
||||
part_iter->part_nums.cur= part_iter->part_nums.start;
|
||||
if (part_iter->part_nums.start == max_endpoint_val)
|
||||
return 0; /* No partitions */
|
||||
@@ -6851,6 +6911,7 @@ int get_part_iter_for_interval_via_walking(partition_info *part_info,
|
||||
Field *field;
|
||||
uint total_parts;
|
||||
partition_iter_func get_next_func;
|
||||
part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
|
||||
if (is_subpart)
|
||||
{
|
||||
field= part_info->subpart_field_array[0];
|
||||
@@ -6961,7 +7022,13 @@ uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter)
|
||||
{
|
||||
if (part_iter->part_nums.cur >= part_iter->part_nums.end)
|
||||
{
|
||||
if (part_iter->ret_null_part)
|
||||
{
|
||||
part_iter->ret_null_part= FALSE;
|
||||
return 0; /* NULL always in first range partition */
|
||||
}
|
||||
part_iter->part_nums.cur= part_iter->part_nums.start;
|
||||
part_iter->ret_null_part= part_iter->ret_null_part_orig;
|
||||
return NOT_A_PARTITION_ID;
|
||||
}
|
||||
else
|
||||
@@ -6989,7 +7056,7 @@ uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter)
|
||||
|
||||
uint32 get_next_partition_id_list(PARTITION_ITERATOR *part_iter)
|
||||
{
|
||||
if (part_iter->part_nums.cur == part_iter->part_nums.end)
|
||||
if (part_iter->part_nums.cur >= part_iter->part_nums.end)
|
||||
{
|
||||
if (part_iter->ret_null_part)
|
||||
{
|
||||
|
Reference in New Issue
Block a user