mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge newbox:mysql-5.1-ppruning-r4
into pylon.mylan:/home/psergey/mysql-5.1-26dec-merge
This commit is contained in:
@ -2478,17 +2478,96 @@ bool get_partition_id_list(partition_info *part_info,
|
||||
if (list_value < part_func_value)
|
||||
min_list_index= list_index + 1;
|
||||
else if (list_value > part_func_value)
|
||||
{
|
||||
if (!list_index)
|
||||
goto notfound;
|
||||
max_list_index= list_index - 1;
|
||||
else {
|
||||
}
|
||||
else
|
||||
{
|
||||
*part_id= (uint32)list_array[list_index].partition_id;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
}
|
||||
notfound:
|
||||
*part_id= 0;
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Find the sub-array part_info->list_array that corresponds to given interval
|
||||
|
||||
SYNOPSIS
|
||||
get_list_array_idx_for_endpoint()
|
||||
part_info Partitioning info (partitioning type must be LIST)
|
||||
left_endpoint TRUE - the interval is [a; +inf) or (a; +inf)
|
||||
FALSE - the interval is (-inf; a] or (-inf; a)
|
||||
include_endpoint TRUE iff the interval includes the endpoint
|
||||
|
||||
DESCRIPTION
|
||||
This function finds the sub-array of part_info->list_array where values of
|
||||
list_array[idx].list_value are contained within the specifed interval.
|
||||
list_array is ordered by list_value, so
|
||||
1. For [a; +inf) or (a; +inf)-type intervals (left_endpoint==TRUE), the
|
||||
sought sub-array starts at some index idx and continues till array end.
|
||||
The function returns first number idx, such that
|
||||
list_array[idx].list_value is contained within the passed interval.
|
||||
|
||||
2. For (-inf; a] or (-inf; a)-type intervals (left_endpoint==FALSE), the
|
||||
sought sub-array starts at array start and continues till some last
|
||||
index idx.
|
||||
The function returns first number idx, such that
|
||||
list_array[idx].list_value is NOT contained within the passed interval.
|
||||
If all array elements are contained, part_info->no_list_values is
|
||||
returned.
|
||||
|
||||
NOTE
|
||||
The caller will call this function and then will run along the sub-array of
|
||||
list_array to collect partition ids. If the number of list values is
|
||||
significantly higher then number of partitions, this could be slow and
|
||||
we could invent some other approach. The "run over list array" part is
|
||||
already wrapped in a get_next()-like function.
|
||||
|
||||
RETURN
|
||||
The edge of corresponding sub-array of part_info->list_array
|
||||
*/
|
||||
|
||||
uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
|
||||
bool left_endpoint,
|
||||
bool include_endpoint)
|
||||
{
|
||||
DBUG_ENTER("get_list_array_idx_for_endpoint");
|
||||
LIST_PART_ENTRY *list_array= part_info->list_array;
|
||||
uint list_index;
|
||||
longlong list_value;
|
||||
uint min_list_index= 0, max_list_index= part_info->no_list_values - 1;
|
||||
/* Get the partitioning function value for the endpoint */
|
||||
longlong part_func_value= part_info->part_expr->val_int();
|
||||
while (max_list_index >= min_list_index)
|
||||
{
|
||||
list_index= (max_list_index + min_list_index) >> 1;
|
||||
list_value= list_array[list_index].list_value;
|
||||
if (list_value < part_func_value)
|
||||
min_list_index= list_index + 1;
|
||||
else if (list_value > part_func_value)
|
||||
{
|
||||
if (!list_index)
|
||||
goto notfound;
|
||||
max_list_index= list_index - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_RETURN(list_index + test(left_endpoint ^ include_endpoint));
|
||||
}
|
||||
}
|
||||
notfound:
|
||||
if (list_value < part_func_value)
|
||||
list_index++;
|
||||
DBUG_RETURN(list_index);
|
||||
}
|
||||
|
||||
|
||||
bool get_partition_id_range(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
{
|
||||
@ -2517,6 +2596,89 @@ bool get_partition_id_range(partition_info *part_info,
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Find the sub-array of part_info->range_int_array that covers given interval
|
||||
|
||||
SYNOPSIS
|
||||
get_partition_id_range_for_endpoint()
|
||||
part_info Partitioning info (partitioning type must be RANGE)
|
||||
left_endpoint TRUE - the interval is [a; +inf) or (a; +inf)
|
||||
FALSE - the interval is (-inf; a] or (-inf; a).
|
||||
include_endpoint TRUE <=> the endpoint itself is included in the
|
||||
interval
|
||||
|
||||
DESCRIPTION
|
||||
This function finds the sub-array of part_info->range_int_array where the
|
||||
elements have non-empty intersections with the given interval.
|
||||
|
||||
A range_int_array element at index idx represents the interval
|
||||
|
||||
[range_int_array[idx-1], range_int_array[idx]),
|
||||
|
||||
intervals are disjoint and ordered by their right bound, so
|
||||
|
||||
1. For [a; +inf) or (a; +inf)-type intervals (left_endpoint==TRUE), the
|
||||
sought sub-array starts at some index idx and continues till array end.
|
||||
The function returns first number idx, such that the interval
|
||||
represented by range_int_array[idx] has non empty intersection with
|
||||
the passed interval.
|
||||
|
||||
2. For (-inf; a] or (-inf; a)-type intervals (left_endpoint==FALSE), the
|
||||
sought sub-array starts at array start and continues till some last
|
||||
index idx.
|
||||
The function returns first number idx, such that the interval
|
||||
represented by range_int_array[idx] has EMPTY intersection with the
|
||||
passed interval.
|
||||
If the interval represented by the last array element has non-empty
|
||||
intersection with the passed interval, part_info->no_parts is
|
||||
returned.
|
||||
|
||||
RETURN
|
||||
The edge of corresponding part_info->range_int_array sub-array.
|
||||
*/
|
||||
|
||||
uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
|
||||
bool left_endpoint,
|
||||
bool include_endpoint)
|
||||
{
|
||||
DBUG_ENTER("get_partition_id_range_for_endpoint");
|
||||
longlong *range_array= part_info->range_int_array;
|
||||
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 */
|
||||
longlong part_func_value= part_info->part_expr->val_int();
|
||||
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)
|
||||
min_part_id= loc_part_id + 1;
|
||||
else
|
||||
max_part_id= loc_part_id - 1;
|
||||
}
|
||||
loc_part_id= max_part_id;
|
||||
if (loc_part_id < max_partition &&
|
||||
part_func_value >= range_array[loc_part_id+1])
|
||||
{
|
||||
loc_part_id++;
|
||||
}
|
||||
if (left_endpoint)
|
||||
{
|
||||
if (part_func_value >= range_array[loc_part_id])
|
||||
loc_part_id++;
|
||||
}
|
||||
else
|
||||
{
|
||||
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++;
|
||||
loc_part_id++;
|
||||
}
|
||||
DBUG_RETURN(loc_part_id);
|
||||
}
|
||||
|
||||
|
||||
bool get_partition_id_hash_nosub(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
{
|
||||
@ -3205,10 +3367,16 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf,
|
||||
*/
|
||||
uint part_func_len= part_info->part_func_len;
|
||||
uint subpart_func_len= part_info->subpart_func_len;
|
||||
uint bitmap_bits= part_info->no_subparts?
|
||||
(part_info->no_subparts* part_info->no_parts):
|
||||
part_info->no_parts;
|
||||
uint bitmap_bytes= bitmap_buffer_size(bitmap_bits);
|
||||
uint32 *bitmap_buf;
|
||||
char *part_func_string, *subpart_func_string= NULL;
|
||||
if (!((part_func_string= thd->alloc(part_func_len))) ||
|
||||
(subpart_func_len &&
|
||||
!((subpart_func_string= thd->alloc(subpart_func_len)))))
|
||||
!((subpart_func_string= thd->alloc(subpart_func_len)))) ||
|
||||
!((bitmap_buf= (uint32*)thd->alloc(bitmap_bytes))))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), part_func_len);
|
||||
free_items(thd->free_list);
|
||||
@ -3221,6 +3389,8 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf,
|
||||
subpart_func_len);
|
||||
part_info->part_func_string= part_func_string;
|
||||
part_info->subpart_func_string= subpart_func_string;
|
||||
|
||||
bitmap_init(&part_info->used_partitions, bitmap_buf, bitmap_bytes*8, FALSE);
|
||||
}
|
||||
|
||||
result= FALSE;
|
||||
@ -3294,3 +3464,60 @@ void set_key_field_ptr(KEY *key_info, const byte *new_buf,
|
||||
} while (++i < key_parts);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Fill the string comma-separated line of used partitions names
|
||||
SYNOPSIS
|
||||
make_used_partitions_str()
|
||||
part_info IN Partitioning info
|
||||
parts_str OUT The string to fill
|
||||
*/
|
||||
|
||||
void make_used_partitions_str(partition_info *part_info, String *parts_str)
|
||||
{
|
||||
parts_str->length(0);
|
||||
partition_element *pe;
|
||||
uint partition_id= 0;
|
||||
List_iterator<partition_element> it(part_info->partitions);
|
||||
|
||||
if (part_info->subpart_type != NOT_A_PARTITION)
|
||||
{
|
||||
partition_element *head_pe;
|
||||
while ((head_pe= it++))
|
||||
{
|
||||
List_iterator<partition_element> it2(head_pe->subpartitions);
|
||||
while ((pe= it2++))
|
||||
{
|
||||
if (bitmap_is_set(&part_info->used_partitions, partition_id))
|
||||
{
|
||||
if (parts_str->length())
|
||||
parts_str->append(',');
|
||||
parts_str->append(head_pe->partition_name,
|
||||
strlen(head_pe->partition_name),
|
||||
system_charset_info);
|
||||
parts_str->append('_');
|
||||
parts_str->append(pe->partition_name,
|
||||
strlen(pe->partition_name),
|
||||
system_charset_info);
|
||||
}
|
||||
partition_id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((pe= it++))
|
||||
{
|
||||
if (bitmap_is_set(&part_info->used_partitions, partition_id))
|
||||
{
|
||||
if (parts_str->length())
|
||||
parts_str->append(',');
|
||||
parts_str->append(pe->partition_name, strlen(pe->partition_name),
|
||||
system_charset_info);
|
||||
}
|
||||
partition_id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user