1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00
This commit is contained in:
Igor Babaev
2009-11-09 18:32:39 -08:00
257 changed files with 12403 additions and 2740 deletions

View File

@ -2767,8 +2767,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);
@ -2917,11 +2933,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)
@ -6078,6 +6112,9 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
lpt->pack_frm_len= 0;
thd->work_part_info= part_info;
/* Never update timestamp columns when alter */
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
if (fast_alter_partition & HA_PARTITION_ONE_PHASE)
{
/*
@ -6694,6 +6731,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;
@ -6731,6 +6769,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
@ -6763,6 +6818,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 */
@ -6847,6 +6910,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];
@ -6957,7 +7021,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
@ -6985,7 +7055,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)
{