summaryrefslogtreecommitdiff
path: root/sql/item_strfunc.h
diff options
context:
space:
mode:
authorunknown <bar@mysql.com>2005-11-21 17:26:31 +0400
committerunknown <bar@mysql.com>2005-11-21 17:26:31 +0400
commit72d19611d198164e1fcd2e16b270a11824d860bf (patch)
tree05c91bc3d02c0f22aab0913b8e7228667bb5ff38 /sql/item_strfunc.h
parent83bbd30c480d97f57203b999cff4517f5e04bf13 (diff)
downloadmariadb-git-72d19611d198164e1fcd2e16b270a11824d860bf.tar.gz
Bug#10446 Illegal mix of collations:
item_strfunc.h, item_strfunc.cc, item.cc: Try to convert a const item into destination character set. If conversion happens without data loss, then cache the converted value and return it during val_str(). Otherwise, if conversion loses data, return Illeral mix of collations error, as it happened previously. ctype_recoding.result, ctype_recoding.test: Fixing tests accordingly. sql/item.cc: Bug#10446 Illegal mix of collations Try to convert a const item into destination character set. If conversion happens without data loss, then cache the converted value and return it during val_str(). Otherwise, if conversion loses data, return Illeral mix of collations error, as it happened previously. sql/item_strfunc.cc: Return cached value when it's possible. mysql-test/t/ctype_recoding.test: Fixing tests accordingly. mysql-test/r/ctype_recoding.result: Fixing tests accordingly.
Diffstat (limited to 'sql/item_strfunc.h')
-rw-r--r--sql/item_strfunc.h34
1 files changed, 32 insertions, 2 deletions
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 87aee9ac25c..c4505fce248 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -614,10 +614,40 @@ public:
class Item_func_conv_charset :public Item_str_func
{
+ bool use_cached_value;
public:
+ bool safe;
CHARSET_INFO *conv_charset; // keep it public
- Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a)
- { conv_charset=cs; }
+ Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a)
+ { conv_charset= cs; use_cached_value= 0; safe= 0; }
+ Item_func_conv_charset(Item *a, CHARSET_INFO *cs, bool cache_if_const)
+ :Item_str_func(a)
+ {
+ DBUG_ASSERT(args[0]->fixed);
+ conv_charset= cs;
+ if (cache_if_const && args[0]->const_item())
+ {
+ uint errors= 0;
+ String tmp, *str= args[0]->val_str(&tmp);
+ if (!str || str_value.copy(str->ptr(), str->length(),
+ str->charset(), conv_charset, &errors))
+ null_value= 1;
+ use_cached_value= 1;
+ safe= (errors == 0);
+ }
+ else
+ {
+ use_cached_value= 0;
+ /*
+ Conversion from and to "binary" is safe.
+ Conversion to Unicode is safe.
+ Other kind of conversions are potentially lossy.
+ */
+ safe= (args[0]->collation.collation == &my_charset_bin ||
+ cs == &my_charset_bin ||
+ (cs->state & MY_CS_UNICODE));
+ }
+ }
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "convert"; }