MDEV-10772 Introduce Item_param::CONVERSION_INFO
This commit is contained in:
parent
62d1cfe16c
commit
8ea2e143f0
57
sql/item.cc
57
sql/item.cc
@ -3412,6 +3412,32 @@ bool Item_param::set_longdata(const char *str, ulong length)
|
||||
}
|
||||
|
||||
|
||||
void Item_param::CONVERSION_INFO::set(THD *thd, CHARSET_INFO *fromcs)
|
||||
{
|
||||
CHARSET_INFO *tocs= thd->variables.collation_connection;
|
||||
|
||||
character_set_of_placeholder= fromcs;
|
||||
character_set_client= thd->variables.character_set_client;
|
||||
/*
|
||||
Setup source and destination character sets so that they
|
||||
are different only if conversion is necessary: this will
|
||||
make later checks easier.
|
||||
*/
|
||||
uint32 dummy_offset;
|
||||
final_character_set_of_str_value=
|
||||
String::needs_conversion(0, fromcs, tocs, &dummy_offset) ?
|
||||
tocs : fromcs;
|
||||
}
|
||||
|
||||
|
||||
bool Item_param::CONVERSION_INFO::convert(THD *thd, String *str)
|
||||
{
|
||||
return thd->convert_string(str,
|
||||
character_set_of_placeholder,
|
||||
final_character_set_of_str_value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Set parameter value from user variable value.
|
||||
|
||||
@ -3451,20 +3477,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
|
||||
break;
|
||||
case STRING_RESULT:
|
||||
{
|
||||
CHARSET_INFO *fromcs= entry->charset();
|
||||
CHARSET_INFO *tocs= thd->variables.collation_connection;
|
||||
uint32 dummy_offset;
|
||||
|
||||
value.cs_info.character_set_of_placeholder= fromcs;
|
||||
value.cs_info.character_set_client= thd->variables.character_set_client;
|
||||
/*
|
||||
Setup source and destination character sets so that they
|
||||
are different only if conversion is necessary: this will
|
||||
make later checks easier.
|
||||
*/
|
||||
value.cs_info.final_character_set_of_str_value=
|
||||
String::needs_conversion(0, fromcs, tocs, &dummy_offset) ?
|
||||
tocs : fromcs;
|
||||
value.cs_info.set(thd, entry->charset());
|
||||
/*
|
||||
Exact value of max_length is not known unless data is converted to
|
||||
charset of connection, so we have to set it later.
|
||||
@ -3775,21 +3788,7 @@ bool Item_param::convert_str_value(THD *thd)
|
||||
bool rc= FALSE;
|
||||
if (state == STRING_VALUE || state == LONG_DATA_VALUE)
|
||||
{
|
||||
/*
|
||||
Check is so simple because all charsets were set up properly
|
||||
in setup_one_conversion_function, where typecode of
|
||||
placeholder was also taken into account: the variables are different
|
||||
here only if conversion is really necessary.
|
||||
*/
|
||||
if (value.cs_info.final_character_set_of_str_value !=
|
||||
value.cs_info.character_set_of_placeholder)
|
||||
{
|
||||
rc= thd->convert_string(&str_value,
|
||||
value.cs_info.character_set_of_placeholder,
|
||||
value.cs_info.final_character_set_of_str_value);
|
||||
}
|
||||
else
|
||||
str_value.set_charset(value.cs_info.final_character_set_of_str_value);
|
||||
rc= value.cs_info.convert_if_needed(thd, &str_value);
|
||||
/* Here str_value is guaranteed to be in final_character_set_of_str_value */
|
||||
|
||||
/*
|
||||
|
60
sql/item.h
60
sql/item.h
@ -2727,6 +2727,47 @@ public:
|
||||
DECIMAL_VALUE
|
||||
} state;
|
||||
|
||||
struct CONVERSION_INFO
|
||||
{
|
||||
/*
|
||||
Character sets conversion info for string values.
|
||||
Character sets of client and connection defined at bind time are used
|
||||
for all conversions, even if one of them is later changed (i.e.
|
||||
between subsequent calls to mysql_stmt_execute).
|
||||
*/
|
||||
CHARSET_INFO *character_set_client;
|
||||
CHARSET_INFO *character_set_of_placeholder;
|
||||
/*
|
||||
This points at character set of connection if conversion
|
||||
to it is required (i. e. if placeholder typecode is not BLOB).
|
||||
Otherwise it's equal to character_set_client (to simplify
|
||||
check in convert_str_value()).
|
||||
*/
|
||||
CHARSET_INFO *final_character_set_of_str_value;
|
||||
private:
|
||||
bool needs_conversion() const
|
||||
{
|
||||
return final_character_set_of_str_value !=
|
||||
character_set_of_placeholder;
|
||||
}
|
||||
bool convert(THD *thd, String *str);
|
||||
public:
|
||||
void set(THD *thd, CHARSET_INFO *cs);
|
||||
bool convert_if_needed(THD *thd, String *str)
|
||||
{
|
||||
/*
|
||||
Check is so simple because all charsets were set up properly
|
||||
in setup_one_conversion_function, where typecode of
|
||||
placeholder was also taken into account: the variables are different
|
||||
here only if conversion is really necessary.
|
||||
*/
|
||||
if (needs_conversion())
|
||||
return convert(thd, str);
|
||||
str->set_charset(final_character_set_of_str_value);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
A buffer for string and long data values. Historically all allocated
|
||||
values returned from val_str() were treated as eligible to
|
||||
@ -2743,24 +2784,7 @@ public:
|
||||
{
|
||||
longlong integer;
|
||||
double real;
|
||||
/*
|
||||
Character sets conversion info for string values.
|
||||
Character sets of client and connection defined at bind time are used
|
||||
for all conversions, even if one of them is later changed (i.e.
|
||||
between subsequent calls to mysql_stmt_execute).
|
||||
*/
|
||||
struct CONVERSION_INFO
|
||||
{
|
||||
CHARSET_INFO *character_set_client;
|
||||
CHARSET_INFO *character_set_of_placeholder;
|
||||
/*
|
||||
This points at character set of connection if conversion
|
||||
to it is required (i. e. if placeholder typecode is not BLOB).
|
||||
Otherwise it's equal to character_set_client (to simplify
|
||||
check in convert_str_value()).
|
||||
*/
|
||||
CHARSET_INFO *final_character_set_of_str_value;
|
||||
} cs_info;
|
||||
CONVERSION_INFO cs_info;
|
||||
MYSQL_TIME time;
|
||||
} value;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user