mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-20856 Bad values in metadata views for partitions on VARBINARY
The old code to print partition values was too complicated: - it created new Items for character set conversion purposes. - it mixed string conversion and partition error reporting in the same code blocks. Simplifying the code as follows: - Adding helper methods String::can_be_safely_convert_to() and String::append_introducer_and_hex(). - Adding DBUG_EXECUTE_IF("generate_partition_syntax_for_frm", push_warning...) into generate_partition_syntax_for_frm(), to test the PARTITON clause written to FRM. Adding test partition_utf8-debug.test for this. - Removing functions get_cs_converted_part_value_from_string() and get_cs_converted_string_value. Changing get_partition_column_description() to use Type_handler::partition_field_append_value() instead. This makes SHOW CREATE TABLE and SELECT FROM I_S.PARTITIONS use the same code path. - Changing Type_handler::partition_field_append_value() not to call convert_charset_partition_constant(), to avoid creating a new Item for string conversion pursposes. Rewritting the code to use only String methods. - Removing error reporting code (ER_PARTITION_FUNCTION_IS_NOT_ALLOWED) from Type_handler::partition_field_append_value(). The error is correctly detected and reported on the caller level. So error reporting was redundant here. Also: - Moving methods Type_handler::partition_field_*() from sql_partition.cc to sql_type.cc. This fixes compilation problem with -DPLUGIN_PARTITION=NO, earlier introduced by the patch for MDEV-20831.
This commit is contained in:
175
sql/sql_show.cc
175
sql/sql_show.cc
@ -122,14 +122,6 @@ static const char *ha_choice_values[] = {"", "0", "1"};
|
||||
|
||||
static void store_key_options(THD *, String *, TABLE *, KEY *);
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
static void get_cs_converted_string_value(THD *thd,
|
||||
String *input_str,
|
||||
String *output_str,
|
||||
CHARSET_INFO *cs,
|
||||
bool use_hex);
|
||||
#endif
|
||||
|
||||
static int show_create_view(THD *thd, TABLE_LIST *table, String *buff);
|
||||
static int show_create_sequence(THD *thd, TABLE_LIST *table_list,
|
||||
String *packet);
|
||||
@ -7124,56 +7116,6 @@ static void collect_partition_expr(THD *thd, List<const char> &field_list,
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Convert a string in a given character set to a string which can be
|
||||
used for FRM file storage in which case use_hex is TRUE and we store
|
||||
the character constants as hex strings in the character set encoding
|
||||
their field have. In the case of SHOW CREATE TABLE and the
|
||||
PARTITIONS information schema table we instead provide utf8 strings
|
||||
to the user and convert to the utf8 character set.
|
||||
|
||||
SYNOPSIS
|
||||
get_cs_converted_part_value_from_string()
|
||||
item Item from which constant comes
|
||||
input_str String as provided by val_str after
|
||||
conversion to character set
|
||||
output_str Out value: The string created
|
||||
cs Character set string is encoded in
|
||||
NULL for INT_RESULT's here
|
||||
use_hex TRUE => hex string created
|
||||
FALSE => utf8 constant string created
|
||||
|
||||
RETURN VALUES
|
||||
TRUE Error
|
||||
FALSE Ok
|
||||
*/
|
||||
|
||||
int get_cs_converted_part_value_from_string(THD *thd,
|
||||
Item *item,
|
||||
String *input_str,
|
||||
String *output_str,
|
||||
CHARSET_INFO *cs,
|
||||
bool use_hex)
|
||||
{
|
||||
if (item->result_type() == INT_RESULT)
|
||||
{
|
||||
longlong value= item->val_int();
|
||||
output_str->set(value, system_charset_info);
|
||||
return FALSE;
|
||||
}
|
||||
if (!input_str)
|
||||
{
|
||||
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
|
||||
return TRUE;
|
||||
}
|
||||
get_cs_converted_string_value(thd,
|
||||
input_str,
|
||||
output_str,
|
||||
cs,
|
||||
use_hex);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -7265,24 +7207,14 @@ static int get_partition_column_description(THD *thd, partition_info *part_info,
|
||||
tmp_str.append("NULL");
|
||||
else
|
||||
{
|
||||
char buffer[MAX_KEY_LENGTH];
|
||||
String str(buffer, sizeof(buffer), &my_charset_bin);
|
||||
String val_conv;
|
||||
Item *item= col_val->item_expression;
|
||||
|
||||
if (!(item= part_info->get_column_item(item,
|
||||
part_info->part_field_array[i])))
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
String *res= item->val_str(&str);
|
||||
if (get_cs_converted_part_value_from_string(thd, item, res, &val_conv,
|
||||
part_info->part_field_array[i]->charset(),
|
||||
FALSE))
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
tmp_str.append(val_conv);
|
||||
StringBuffer<MAX_KEY_LENGTH> val;
|
||||
const Field *field= part_info->part_field_array[i];
|
||||
const Type_handler *th= field->type_handler();
|
||||
th->partition_field_append_value(&val, item,
|
||||
field->charset(),
|
||||
PARTITION_VALUE_PRINT_MODE_SHOW);
|
||||
tmp_str.append(val);
|
||||
}
|
||||
if (i != num_elements - 1)
|
||||
tmp_str.append(",");
|
||||
@ -9964,99 +9896,6 @@ void initialize_information_schema_acl()
|
||||
&is_internal_schema_access);
|
||||
}
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
/*
|
||||
Convert a string in character set in column character set format
|
||||
to utf8 character set if possible, the utf8 character set string
|
||||
will later possibly be converted to character set used by client.
|
||||
Thus we attempt conversion from column character set to both
|
||||
utf8 and to character set client.
|
||||
|
||||
Examples of strings that should fail conversion to utf8 are unassigned
|
||||
characters as e.g. 0x81 in cp1250 (Windows character set for for countries
|
||||
like Czech and Poland). Example of string that should fail conversion to
|
||||
character set on client (e.g. if this is latin1) is 0x2020 (daggger) in
|
||||
ucs2.
|
||||
|
||||
If the conversion fails we will as a fall back convert the string to
|
||||
hex encoded format. The caller of the function can also ask for hex
|
||||
encoded format of output string unconditionally.
|
||||
|
||||
SYNOPSIS
|
||||
get_cs_converted_string_value()
|
||||
thd Thread object
|
||||
input_str Input string in cs character set
|
||||
output_str Output string to be produced in utf8
|
||||
cs Character set of input string
|
||||
use_hex Use hex string unconditionally
|
||||
|
||||
|
||||
RETURN VALUES
|
||||
No return value
|
||||
*/
|
||||
|
||||
static void get_cs_converted_string_value(THD *thd,
|
||||
String *input_str,
|
||||
String *output_str,
|
||||
CHARSET_INFO *cs,
|
||||
bool use_hex)
|
||||
{
|
||||
|
||||
output_str->length(0);
|
||||
if (input_str->length() == 0)
|
||||
{
|
||||
output_str->append("''");
|
||||
return;
|
||||
}
|
||||
if (!use_hex)
|
||||
{
|
||||
String try_val;
|
||||
uint try_conv_error= 0;
|
||||
|
||||
try_val.copy(input_str->ptr(), input_str->length(), cs,
|
||||
thd->variables.character_set_client, &try_conv_error);
|
||||
if (likely(!try_conv_error))
|
||||
{
|
||||
String val;
|
||||
uint conv_error= 0;
|
||||
|
||||
val.copy(input_str->ptr(), input_str->length(), cs,
|
||||
system_charset_info, &conv_error);
|
||||
if (likely(!conv_error))
|
||||
{
|
||||
append_unescaped(output_str, val.ptr(), val.length());
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* We had a conversion error, use hex encoded string for safety */
|
||||
}
|
||||
{
|
||||
const uchar *ptr;
|
||||
uint i, len;
|
||||
char buf[3];
|
||||
|
||||
output_str->append("_");
|
||||
output_str->append(cs->csname);
|
||||
output_str->append(" ");
|
||||
output_str->append("0x");
|
||||
len= input_str->length();
|
||||
ptr= (uchar*)input_str->ptr();
|
||||
for (i= 0; i < len; i++)
|
||||
{
|
||||
uint high, low;
|
||||
|
||||
high= (*ptr) >> 4;
|
||||
low= (*ptr) & 0x0F;
|
||||
buf[0]= _dig_vec_upper[high];
|
||||
buf[1]= _dig_vec_upper[low];
|
||||
buf[2]= 0;
|
||||
output_str->append((const char*)buf);
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Dumps a text description of a thread, its security context
|
||||
|
Reference in New Issue
Block a user