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.
|
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;
|
break;
|
||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
{
|
{
|
||||||
CHARSET_INFO *fromcs= entry->charset();
|
value.cs_info.set(thd, 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;
|
|
||||||
/*
|
/*
|
||||||
Exact value of max_length is not known unless data is converted to
|
Exact value of max_length is not known unless data is converted to
|
||||||
charset of connection, so we have to set it later.
|
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;
|
bool rc= FALSE;
|
||||||
if (state == STRING_VALUE || state == LONG_DATA_VALUE)
|
if (state == STRING_VALUE || state == LONG_DATA_VALUE)
|
||||||
{
|
{
|
||||||
/*
|
rc= value.cs_info.convert_if_needed(thd, &str_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);
|
|
||||||
/* Here str_value is guaranteed to be in final_character_set_of_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
|
DECIMAL_VALUE
|
||||||
} state;
|
} 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
|
A buffer for string and long data values. Historically all allocated
|
||||||
values returned from val_str() were treated as eligible to
|
values returned from val_str() were treated as eligible to
|
||||||
@ -2743,24 +2784,7 @@ public:
|
|||||||
{
|
{
|
||||||
longlong integer;
|
longlong integer;
|
||||||
double real;
|
double real;
|
||||||
/*
|
CONVERSION_INFO cs_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).
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
MYSQL_TIME time;
|
MYSQL_TIME time;
|
||||||
} value;
|
} value;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user