1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Merge dator5.(none):/home/pappa/clean-mysql-5.1

into  dator5.(none):/home/pappa/bug18198
This commit is contained in:
mikael/pappa@dator5.(none)
2006-10-16 15:40:40 -04:00
28 changed files with 1127 additions and 356 deletions

View File

@ -62,48 +62,64 @@ static const char *end_paren_str= ")";
static const char *begin_paren_str= "(";
static const char *comma_str= ",";
int get_partition_id_list(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_hash_nosub(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_key_nosub(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_linear_hash_nosub(partition_info *part_info,
static int get_part_id_charset_func_all(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_linear_key_nosub(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range_sub_hash(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range_sub_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range_sub_linear_hash(partition_info *part_info,
static int get_part_id_charset_func_part(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
static int get_part_id_charset_func_subpart(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range_sub_linear_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_hash(partition_info *part_info,
static int get_part_part_id_charset_func(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
static uint32 get_subpart_id_charset_func(partition_info *part_info);
int get_partition_id_list(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_hash_nosub(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_key_nosub(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_linear_hash_nosub(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_linear_key_nosub(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_range_sub_hash(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_key(partition_info *part_info,
int get_partition_id_range_sub_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_linear_hash(partition_info *part_info,
int get_partition_id_range_sub_linear_hash(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_linear_key(partition_info *part_info,
int get_partition_id_range_sub_linear_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_hash(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_linear_hash(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
int get_partition_id_list_sub_linear_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
uint32 get_partition_id_hash_sub(partition_info *part_info);
uint32 get_partition_id_key_sub(partition_info *part_info);
uint32 get_partition_id_linear_hash_sub(partition_info *part_info);
@ -525,6 +541,7 @@ static bool set_up_field_array(TABLE *table,
}
/*
Create a field array including all fields of both the partitioning and the
subpartitioning functions.
@ -549,6 +566,7 @@ static bool create_full_part_field_array(TABLE *table,
partition_info *part_info)
{
bool result= FALSE;
Field **ptr;
DBUG_ENTER("create_full_part_field_array");
if (!part_info->is_sub_partitioned())
@ -558,7 +576,7 @@ static bool create_full_part_field_array(TABLE *table,
}
else
{
Field **ptr, *field, **field_array;
Field *field, **field_array;
uint no_part_fields=0, size_field_array;
ptr= table->field;
while ((field= *(ptr++)))
@ -1328,6 +1346,33 @@ static void set_up_partition_func_pointers(partition_info *part_info)
}
}
}
if (part_info->full_part_charset_field_array)
{
DBUG_ASSERT(part_info->get_partition_id);
part_info->get_partition_id_charset= part_info->get_partition_id;
if (part_info->part_charset_field_array &&
part_info->subpart_charset_field_array)
part_info->get_partition_id= get_part_id_charset_func_all;
else if (part_info->part_charset_field_array)
part_info->get_partition_id= get_part_id_charset_func_part;
else
part_info->get_partition_id= get_part_id_charset_func_subpart;
}
if (part_info->part_charset_field_array &&
part_info->is_sub_partitioned())
{
DBUG_ASSERT(part_info->get_part_partition_id);
part_info->get_part_partition_id_charset=
part_info->get_part_partition_id;
part_info->get_part_partition_id= get_part_part_id_charset_func;
}
if (part_info->subpart_charset_field_array)
{
DBUG_ASSERT(part_info->get_subpartition_id);
part_info->get_subpartition_id_charset=
part_info->get_subpartition_id;
part_info->get_subpartition_id= get_subpart_id_charset_func;
}
DBUG_VOID_RETURN;
}
@ -1388,6 +1433,82 @@ static uint32 get_part_id_from_linear_hash(longlong hash_value, uint mask,
return part_id;
}
/*
Check if a particular field is in need of character set
handling for partition functions.
SYNOPSIS
field_is_partition_charset()
field The field to check
RETURN VALUES
FALSE Not in need of character set handling
TRUE In need of character set handling
*/
bool field_is_partition_charset(Field *field)
{
if (!(field->type() == MYSQL_TYPE_STRING) &&
!(field->type() == MYSQL_TYPE_VARCHAR))
return FALSE;
{
CHARSET_INFO *cs= ((Field_str*)field)->charset();
if (!(field->type() == MYSQL_TYPE_STRING) ||
!(cs->state & MY_CS_BINSORT))
return TRUE;
return FALSE;
}
}
/*
Check that partition function doesn't contain any forbidden
character sets and collations.
SYNOPSIS
check_part_func_fields()
ptr Array of Field pointers
ok_with_charsets Will we report allowed charset
fields as ok
RETURN VALUES
FALSE Success
TRUE Error
DESCRIPTION
We will check in this routine that the fields of the partition functions
do not contain unallowed parts. It can also be used to check if there
are fields that require special care by calling my_strnxfrm before
calling the functions to calculate partition id.
*/
bool check_part_func_fields(Field **ptr, bool ok_with_charsets)
{
Field *field;
DBUG_ENTER("check_part_func_fields");
while ((field= *(ptr++)))
{
/*
For CHAR/VARCHAR fields we need to take special precautions.
Binary collation with CHAR is automatically supported. Other
types need some kind of standardisation function handling
*/
if (field_is_partition_charset(field))
{
CHARSET_INFO *cs= ((Field_str*)field)->charset();
if (!ok_with_charsets ||
cs->mbmaxlen > 1 ||
cs->strxfrm_multiply > 1)
{
DBUG_RETURN(TRUE);
}
}
}
DBUG_RETURN(FALSE);
}
/*
fix partition functions
@ -1531,6 +1652,16 @@ bool fix_partition_func(THD *thd, TABLE *table,
goto end;
}
}
if (((part_info->part_type != HASH_PARTITION ||
part_info->list_of_part_fields == FALSE) &&
check_part_func_fields(part_info->part_field_array, TRUE)) ||
(part_info->list_of_part_fields == FALSE &&
part_info->is_sub_partitioned() &&
check_part_func_fields(part_info->subpart_field_array, TRUE)))
{
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
goto end;
}
if (unlikely(create_full_part_field_array(table, part_info)))
goto end;
if (unlikely(check_primary_key(table)))
@ -1541,6 +1672,11 @@ bool fix_partition_func(THD *thd, TABLE *table,
goto end;
if (unlikely(set_up_partition_bitmap(thd, part_info)))
goto end;
if (unlikely(part_info->set_up_charset_field_preps()))
{
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
goto end;
}
check_range_capable_PF(table);
set_up_partition_key_maps(table, part_info);
set_up_partition_func_pointers(part_info);
@ -2254,6 +2390,88 @@ static uint32 get_part_id_linear_key(partition_info *part_info,
no_parts));
}
/*
Copy to field buffers and set up field pointers
SYNOPSIS
copy_to_part_field_buffers()
ptr Array of fields to copy
field_bufs Array of field buffers to copy to
restore_ptr Array of pointers to restore to
RETURN VALUES
NONE
DESCRIPTION
This routine is used to take the data from field pointer, convert
it to a standard format and store this format in a field buffer
allocated for this purpose. Next the field pointers are moved to
point to the field buffers. There is a separate to restore the
field pointers after this call.
*/
static void copy_to_part_field_buffers(Field **ptr,
char **field_bufs,
char **restore_ptr)
{
Field *field;
while ((field= *(ptr++)))
{
*restore_ptr= field->ptr;
restore_ptr++;
if (!field->maybe_null() || !field->is_null())
{
CHARSET_INFO *cs= ((Field_str*)field)->charset();
uint len= field->pack_length();
char *field_buf= *field_bufs;
/*
We only use the field buffer for VARCHAR and CHAR strings
which isn't of a binary collation. We also only use the
field buffer for fields which are not currently NULL.
The field buffer will store a normalised string. We use
the strnxfrm method to normalise the string.
*/
if (field->type() == MYSQL_TYPE_VARCHAR)
{
uint len_bytes= ((Field_varstring*)field)->length_bytes;
my_strnxfrm(cs, (uchar*)(field_buf + len_bytes), (len - len_bytes),
(uchar*)(field->ptr + len_bytes), field->field_length);
if (len_bytes == 1)
*field_buf= (uchar)field->field_length;
else
int2store(field_buf, field->field_length);
}
else
{
my_strnxfrm(cs, (uchar*)field_buf, len,
(uchar*)field->ptr, field->field_length);
}
field->ptr= field_buf;
}
field_bufs++;
}
return;
}
/*
Restore field pointers
SYNOPSIS
restore_part_field_pointers()
ptr Array of fields to restore
restore_ptr Array of field pointers to restore to
RETURN VALUES
*/
static void restore_part_field_pointers(Field **ptr, char **restore_ptr)
{
Field *field;
while ((field= *(ptr++)))
{
field->ptr= *restore_ptr;
restore_ptr++;
}
return;
}
/*
This function is used to calculate the partition id where all partition
fields have been prepared to point to a record where the partition field
@ -2264,6 +2482,7 @@ static uint32 get_part_id_linear_key(partition_info *part_info,
part_info A reference to the partition_info struct where all the
desired information is given
out:part_id The partition id is returned through this pointer
out: func_value Value of partition function (longlong)
RETURN VALUE
part_id Partition id of partition that would contain
@ -2307,6 +2526,7 @@ static uint32 get_part_id_linear_key(partition_info *part_info,
part_info A reference to the partition_info struct where all the
desired information is given
out:part_id The partition id is returned through this pointer
out: func_value The value calculated by partition function
RETURN VALUE
part_id Partition id of partition that would contain
@ -2328,6 +2548,79 @@ static uint32 get_part_id_linear_key(partition_info *part_info,
get_partition_id_linear_key_nosub
*/
static int get_part_id_charset_func_subpart(partition_info *part_info,
uint32 *part_id,
longlong *func_value)
{
int res;
copy_to_part_field_buffers(part_info->subpart_charset_field_array,
part_info->subpart_field_buffers,
part_info->restore_subpart_field_ptrs);
res= part_info->get_partition_id_charset(part_info, part_id, func_value);
restore_part_field_pointers(part_info->subpart_charset_field_array,
part_info->restore_subpart_field_ptrs);
return res;
}
static int get_part_id_charset_func_part(partition_info *part_info,
uint32 *part_id,
longlong *func_value)
{
int res;
copy_to_part_field_buffers(part_info->part_charset_field_array,
part_info->part_field_buffers,
part_info->restore_part_field_ptrs);
res= part_info->get_partition_id_charset(part_info, part_id, func_value);
restore_part_field_pointers(part_info->part_charset_field_array,
part_info->restore_part_field_ptrs);
return res;
}
static int get_part_id_charset_func_all(partition_info *part_info,
uint32 *part_id,
longlong *func_value)
{
int res;
copy_to_part_field_buffers(part_info->full_part_field_array,
part_info->full_part_field_buffers,
part_info->restore_full_part_field_ptrs);
res= part_info->get_partition_id_charset(part_info, part_id, func_value);
restore_part_field_pointers(part_info->full_part_field_array,
part_info->restore_full_part_field_ptrs);
return res;
}
static int get_part_part_id_charset_func(partition_info *part_info,
uint32 *part_id,
longlong *func_value)
{
int res;
copy_to_part_field_buffers(part_info->part_charset_field_array,
part_info->part_field_buffers,
part_info->restore_part_field_ptrs);
res= part_info->get_part_partition_id_charset(part_info,
part_id, func_value);
restore_part_field_pointers(part_info->part_charset_field_array,
part_info->restore_part_field_ptrs);
return res;
}
static uint32 get_subpart_id_charset_func(partition_info *part_info)
{
int res;
copy_to_part_field_buffers(part_info->subpart_charset_field_array,
part_info->subpart_field_buffers,
part_info->restore_subpart_field_ptrs);
res= part_info->get_subpartition_id_charset(part_info);
restore_part_field_pointers(part_info->subpart_charset_field_array,
part_info->restore_subpart_field_ptrs);
return res;
}
int get_partition_id_list(partition_info *part_info,
uint32 *part_id,
@ -2416,6 +2709,21 @@ notfound:
The edge of corresponding sub-array of part_info->list_array
*/
uint32 get_list_array_idx_for_endpoint_charset(partition_info *part_info,
bool left_endpoint,
bool include_endpoint)
{
uint32 res;
copy_to_part_field_buffers(part_info->part_field_array,
part_info->part_field_buffers,
part_info->restore_part_field_ptrs);
res= get_list_array_idx_for_endpoint(part_info, left_endpoint,
include_endpoint);
restore_part_field_pointers(part_info->part_field_array,
part_info->restore_part_field_ptrs);
return res;
}
uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
bool left_endpoint,
bool include_endpoint)
@ -2461,8 +2769,8 @@ notfound:
int get_partition_id_range(partition_info *part_info,
uint32 *part_id,
longlong *func_value)
uint32 *part_id,
longlong *func_value)
{
longlong *range_array= part_info->range_int_array;
uint max_partition= part_info->no_parts - 1;
@ -2545,6 +2853,22 @@ int get_partition_id_range(partition_info *part_info,
The edge of corresponding part_info->range_int_array sub-array.
*/
static uint32
get_partition_id_range_for_endpoint_charset(partition_info *part_info,
bool left_endpoint,
bool include_endpoint)
{
uint32 res;
copy_to_part_field_buffers(part_info->part_field_array,
part_info->part_field_buffers,
part_info->restore_part_field_ptrs);
res= get_partition_id_range_for_endpoint(part_info, left_endpoint,
include_endpoint);
restore_part_field_pointers(part_info->part_field_array,
part_info->restore_part_field_ptrs);
return res;
}
uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
bool left_endpoint,
bool include_endpoint)
@ -4557,7 +4881,7 @@ the generated partition syntax in a correct manner.
tab_part_info->use_default_no_subpartitions= FALSE;
}
if (tab_part_info->check_partition_info(thd, (handlerton**)NULL,
table->file, ULL(0)))
table->file, ULL(0), FALSE))
{
DBUG_RETURN(TRUE);
}
@ -6384,13 +6708,20 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
if (part_info->part_type == RANGE_PARTITION)
{
get_endpoint= get_partition_id_range_for_endpoint;
if (part_info->part_charset_field_array)
get_endpoint= get_partition_id_range_for_endpoint_charset;
else
get_endpoint= get_partition_id_range_for_endpoint;
max_endpoint_val= part_info->no_parts;
part_iter->get_next= get_next_partition_id_range;
}
else if (part_info->part_type == LIST_PARTITION)
{
get_endpoint= get_list_array_idx_for_endpoint;
if (part_info->part_charset_field_array)
get_endpoint= get_list_array_idx_for_endpoint_charset;
else
get_endpoint= get_list_array_idx_for_endpoint;
max_endpoint_val= part_info->no_list_values;
part_iter->get_next= get_next_partition_id_list;
part_iter->part_info= part_info;