diff options
Diffstat (limited to 'sql/sql_partition.cc')
-rw-r--r-- | sql/sql_partition.cc | 195 |
1 files changed, 57 insertions, 138 deletions
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index eb431134d9d..796f018e04b 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1346,20 +1346,19 @@ static void set_up_partition_func_pointers(partition_info *part_info) } } } - if (part_info->includes_charset_field_part || - part_info->includes_charset_field_subpart) + 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->includes_charset_field_part && - part_info->includes_charset_field_subpart) + 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->includes_charset_field_part) + 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->includes_charset_field_part && + if (part_info->part_charset_field_array && part_info->is_sub_partitioned()) { DBUG_ASSERT(part_info->get_part_partition_id); @@ -1367,7 +1366,7 @@ static void set_up_partition_func_pointers(partition_info *part_info) part_info->get_part_partition_id; part_info->get_part_partition_id= get_part_part_id_charset_func; } - if (part_info->includes_charset_field_subpart) + if (part_info->subpart_charset_field_array) { DBUG_ASSERT(part_info->get_subpartition_id); part_info->get_subpartition_id_charset= @@ -1436,6 +1435,32 @@ static uint32 get_part_id_from_linear_hash(longlong hash_value, uint mask, /* + 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 do not contain any forbidden character sets and collations. SYNOPSIS @@ -1453,7 +1478,7 @@ static uint32 get_part_id_from_linear_hash(longlong hash_value, uint mask, calling the functions to calculate partition id. */ -static bool check_part_func_fields(Field **ptr, bool ok_with_charsets) +bool check_part_func_fields(Field **ptr, bool ok_with_charsets) { Field *field; DBUG_ENTER("check_part_func_field"); @@ -1465,13 +1490,9 @@ static bool check_part_func_fields(Field **ptr, bool ok_with_charsets) Binary collation with CHAR is automatically supported. Other types need some kind of standardisation function handling */ - if (field->type() == MYSQL_TYPE_STRING || - field->type() == MYSQL_TYPE_VARCHAR) + if (field_is_partition_charset(field)) { CHARSET_INFO *cs= ((Field_str*)field)->charset(); - if (field->type() == MYSQL_TYPE_STRING && - cs->state & MY_CS_BINSORT) - continue; if (!ok_with_charsets || cs->mbmaxlen > 1 || cs->strxfrm_multiply > 1) @@ -1483,106 +1504,6 @@ static bool check_part_func_fields(Field **ptr, bool ok_with_charsets) DBUG_RETURN(FALSE); } -/* - Set up buffers and arrays for fields requiring preparation - SYNOPSIS - set_up_charset_field_preps() - part_info Partition info object - RETURN VALUES - TRUE Memory Allocation error - FALSE Success - DESCRIPTION - Set up arrays and buffers for fields that require special care for - calculation of partition id. This is used for string fields with - variable length or string fields with fixed length that isn't using - the binary collation. -*/ - -static bool set_up_charset_field_preps(partition_info *part_info) -{ - Field *field, **ptr; - char *field_buf; - char **char_ptrs; - unsigned i; - size_t size; - - DBUG_ENTER("set_up_charset_field_preps"); - if (check_part_func_fields(part_info->part_field_array, FALSE)) - { - ptr= part_info->part_field_array; - part_info->includes_charset_field_part= TRUE; - /* - Set up arrays and buffers for those fields - */ - i= 0; - while ((field= *(ptr++))) - i++; - size= i * sizeof(char*); - - if (!(char_ptrs= (char**)sql_calloc(size))) - goto error; - part_info->part_field_buffers= char_ptrs; - - if (!(char_ptrs= (char**)sql_calloc(size))) - goto error; - part_info->restore_part_field_ptrs= char_ptrs; - - ptr= part_info->part_field_array; - i= 0; - while ((field= *(ptr++))) - { - CHARSET_INFO *cs= ((Field_str*)field)->charset(); - size= field->pack_length(); - if (!(field_buf= sql_calloc(size))) - goto error; - part_info->part_field_buffers[i++]= field_buf; - } - } - if (part_info->is_sub_partitioned() && - check_part_func_fields(part_info->subpart_field_array, FALSE)) - { - /* - Set up arrays and buffers for those fields - */ - part_info->includes_charset_field_subpart= TRUE; - - ptr= part_info->subpart_field_array; - i= 0; - while ((field= *(ptr++))) - { - unsigned j= 0; - Field *part_field; - Field **part_ptr= part_info->part_field_array; - bool field_already_have_buffer= FALSE; - CHARSET_INFO *cs= ((Field_str*)field)->charset(); - size= field->pack_length(); - - while ((part_field= *(part_ptr++))) - { - field_buf= part_info->part_field_buffers[j++]; - if (field == part_field) - { - field_already_have_buffer= TRUE; - break; - } - } - if (!field_already_have_buffer) - { - if (!(field_buf= sql_calloc(size))) - goto error; - } - part_info->subpart_field_buffers[i++]= field_buf; - } - size= i * sizeof(char*); - if (!(char_ptrs= (char**)sql_calloc(i * sizeof(char*)))) - goto error; - part_info->restore_subpart_field_ptrs= char_ptrs; - } - DBUG_RETURN(FALSE); -error: - mem_alloc_error(size); - DBUG_RETURN(TRUE); -} /* fix partition functions @@ -1747,7 +1668,7 @@ bool fix_partition_func(THD *thd, TABLE *table, goto end; if (unlikely(set_up_partition_bitmap(thd, part_info))) goto end; - if (unlikely(set_up_charset_field_preps(part_info))) + if (unlikely(part_info->set_up_charset_field_preps())) { my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0)); goto end; @@ -2491,10 +2412,7 @@ static void copy_to_part_field_buffers(Field **ptr, { *restore_ptr= field->ptr; restore_ptr++; - if ((field->type() == MYSQL_TYPE_VARCHAR || - (field->type() == MYSQL_TYPE_STRING && - (!(((Field_str*)field)->charset()->state & MY_CS_BINSORT))) && - ((!field->maybe_null()) || (!field->is_null())))) + if (!field->maybe_null() || !field->is_null()) { CHARSET_INFO *cs= ((Field_str*)field)->charset(); uint len= field->pack_length(); @@ -2628,74 +2546,75 @@ static int get_part_id_charset_func_subpart(partition_info *part_info, longlong *func_value) { int res; - copy_to_part_field_buffers(part_info->subpart_field_array, + 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_field_array, + 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_field_array, + 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_field_array, + 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->part_field_array, - part_info->part_field_buffers, - part_info->restore_part_field_ptrs); - copy_to_part_field_buffers(part_info->subpart_field_array, - part_info->subpart_field_buffers, - part_info->restore_subpart_field_ptrs); + 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->part_field_array, - part_info->restore_part_field_ptrs); - restore_part_field_pointers(part_info->subpart_field_array, - part_info->restore_subpart_field_ptrs); + 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_field_array, + 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_field_array, + 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_field_array, + 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_field_array, + 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, longlong *func_value) @@ -6782,7 +6701,7 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info, if (part_info->part_type == RANGE_PARTITION) { - if (part_info->includes_charset_field_part) + 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; @@ -6792,7 +6711,7 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info, else if (part_info->part_type == LIST_PARTITION) { - if (part_info->includes_charset_field_part) + 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; |