Skip to content

Commit 8ea2e14

Browse files
author
Alexander Barkov
committed
MDEV-10772 Introduce Item_param::CONVERSION_INFO
1 parent 62d1cfe commit 8ea2e14

File tree

2 files changed

+70
-47
lines changed

2 files changed

+70
-47
lines changed

sql/item.cc

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3412,6 +3412,32 @@ bool Item_param::set_longdata(const char *str, ulong length)
34123412
}
34133413

34143414

3415+
void Item_param::CONVERSION_INFO::set(THD *thd, CHARSET_INFO *fromcs)
3416+
{
3417+
CHARSET_INFO *tocs= thd->variables.collation_connection;
3418+
3419+
character_set_of_placeholder= fromcs;
3420+
character_set_client= thd->variables.character_set_client;
3421+
/*
3422+
Setup source and destination character sets so that they
3423+
are different only if conversion is necessary: this will
3424+
make later checks easier.
3425+
*/
3426+
uint32 dummy_offset;
3427+
final_character_set_of_str_value=
3428+
String::needs_conversion(0, fromcs, tocs, &dummy_offset) ?
3429+
tocs : fromcs;
3430+
}
3431+
3432+
3433+
bool Item_param::CONVERSION_INFO::convert(THD *thd, String *str)
3434+
{
3435+
return thd->convert_string(str,
3436+
character_set_of_placeholder,
3437+
final_character_set_of_str_value);
3438+
}
3439+
3440+
34153441
/**
34163442
Set parameter value from user variable value.
34173443
@@ -3451,20 +3477,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
34513477
break;
34523478
case STRING_RESULT:
34533479
{
3454-
CHARSET_INFO *fromcs= entry->charset();
3455-
CHARSET_INFO *tocs= thd->variables.collation_connection;
3456-
uint32 dummy_offset;
3457-
3458-
value.cs_info.character_set_of_placeholder= fromcs;
3459-
value.cs_info.character_set_client= thd->variables.character_set_client;
3460-
/*
3461-
Setup source and destination character sets so that they
3462-
are different only if conversion is necessary: this will
3463-
make later checks easier.
3464-
*/
3465-
value.cs_info.final_character_set_of_str_value=
3466-
String::needs_conversion(0, fromcs, tocs, &dummy_offset) ?
3467-
tocs : fromcs;
3480+
value.cs_info.set(thd, entry->charset());
34683481
/*
34693482
Exact value of max_length is not known unless data is converted to
34703483
charset of connection, so we have to set it later.
@@ -3775,21 +3788,7 @@ bool Item_param::convert_str_value(THD *thd)
37753788
bool rc= FALSE;
37763789
if (state == STRING_VALUE || state == LONG_DATA_VALUE)
37773790
{
3778-
/*
3779-
Check is so simple because all charsets were set up properly
3780-
in setup_one_conversion_function, where typecode of
3781-
placeholder was also taken into account: the variables are different
3782-
here only if conversion is really necessary.
3783-
*/
3784-
if (value.cs_info.final_character_set_of_str_value !=
3785-
value.cs_info.character_set_of_placeholder)
3786-
{
3787-
rc= thd->convert_string(&str_value,
3788-
value.cs_info.character_set_of_placeholder,
3789-
value.cs_info.final_character_set_of_str_value);
3790-
}
3791-
else
3792-
str_value.set_charset(value.cs_info.final_character_set_of_str_value);
3791+
rc= value.cs_info.convert_if_needed(thd, &str_value);
37933792
/* Here str_value is guaranteed to be in final_character_set_of_str_value */
37943793

37953794
/*

sql/item.h

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2727,6 +2727,47 @@ class Item_param :public Item_basic_value,
27272727
DECIMAL_VALUE
27282728
} state;
27292729

2730+
struct CONVERSION_INFO
2731+
{
2732+
/*
2733+
Character sets conversion info for string values.
2734+
Character sets of client and connection defined at bind time are used
2735+
for all conversions, even if one of them is later changed (i.e.
2736+
between subsequent calls to mysql_stmt_execute).
2737+
*/
2738+
CHARSET_INFO *character_set_client;
2739+
CHARSET_INFO *character_set_of_placeholder;
2740+
/*
2741+
This points at character set of connection if conversion
2742+
to it is required (i. e. if placeholder typecode is not BLOB).
2743+
Otherwise it's equal to character_set_client (to simplify
2744+
check in convert_str_value()).
2745+
*/
2746+
CHARSET_INFO *final_character_set_of_str_value;
2747+
private:
2748+
bool needs_conversion() const
2749+
{
2750+
return final_character_set_of_str_value !=
2751+
character_set_of_placeholder;
2752+
}
2753+
bool convert(THD *thd, String *str);
2754+
public:
2755+
void set(THD *thd, CHARSET_INFO *cs);
2756+
bool convert_if_needed(THD *thd, String *str)
2757+
{
2758+
/*
2759+
Check is so simple because all charsets were set up properly
2760+
in setup_one_conversion_function, where typecode of
2761+
placeholder was also taken into account: the variables are different
2762+
here only if conversion is really necessary.
2763+
*/
2764+
if (needs_conversion())
2765+
return convert(thd, str);
2766+
str->set_charset(final_character_set_of_str_value);
2767+
return false;
2768+
}
2769+
};
2770+
27302771
/*
27312772
A buffer for string and long data values. Historically all allocated
27322773
values returned from val_str() were treated as eligible to
@@ -2743,24 +2784,7 @@ class Item_param :public Item_basic_value,
27432784
{
27442785
longlong integer;
27452786
double real;
2746-
/*
2747-
Character sets conversion info for string values.
2748-
Character sets of client and connection defined at bind time are used
2749-
for all conversions, even if one of them is later changed (i.e.
2750-
between subsequent calls to mysql_stmt_execute).
2751-
*/
2752-
struct CONVERSION_INFO
2753-
{
2754-
CHARSET_INFO *character_set_client;
2755-
CHARSET_INFO *character_set_of_placeholder;
2756-
/*
2757-
This points at character set of connection if conversion
2758-
to it is required (i. e. if placeholder typecode is not BLOB).
2759-
Otherwise it's equal to character_set_client (to simplify
2760-
check in convert_str_value()).
2761-
*/
2762-
CHARSET_INFO *final_character_set_of_str_value;
2763-
} cs_info;
2787+
CONVERSION_INFO cs_info;
27642788
MYSQL_TIME time;
27652789
} value;
27662790

0 commit comments

Comments
 (0)